package com.yiyihealth.cherriesadmin.config;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Set;

/**
 * DAO切面，插入创建人，创建时间，修改人，修改时间
 * @author Louis
 * @date Oct 29, 2018
 */
@Order(2)
@Aspect
@Component
@Slf4j
public class AopCache {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RedisTemplate<Object, Object> redisCacheTemplate;

	@Pointcut("execution(public * com.yiyihealth.cherriesadmin.core.service.*.*updateBy*(..))")
	public void daoUpdate() {
	}

	@Pointcut("execution(public * com.yiyihealth.cherriesadmin.core.service.*.*insert*(..))")
	public void daoCreate() {
	}

	@Pointcut("execution(public * com.yiyihealth.cherriesadmin.core.service.*.*deleteBy*(..))")
	public void daoDeleteBy() {
	}

	/**
	 * 环绕操作
	 *
	 * @param pjp 切入点
	 * @return 原方法返回值
	 * @throws Throwable 异常信息
	 */
	@Around("daoUpdate()")
	public Object doAroundUpdate(ProceedingJoinPoint pjp) throws Throwable {
		log.info("Around: daoUpdate");
		Object object = pjp.proceed();
		return object;

	}

	/**
	 * 环绕操作
	 *
	 * @param pjp 切入点
	 * @return 原方法返回值
	 * @throws Throwable 异常信息
	 */
	@Around("daoCreate()")
	public Object doAroundCreate(ProceedingJoinPoint pjp) throws Throwable {
		log.info("Around: daoCreate");
		Object object = pjp.proceed();
		return object;
	}
	/**
	 * 环绕操作
	 *
	 * @param pjp 切入点
	 * @return 原方法返回值
	 * @throws Throwable 异常信息
	 */
	@Around("daoDeleteBy()")
	public Object doAroundDelete(ProceedingJoinPoint pjp) throws Throwable {
		log.info("Around: daoCreate");
		Object object = pjp.proceed();
		return object;
	}

	/**
	 * 后置操作
	 */
	@AfterReturning("daoCreate()")
	public void createAfterReturning(JoinPoint joinPoint) {
		cleanRedisCache(joinPoint);
	}

	/**
	 * 后置操作
	 */
	@AfterReturning("daoUpdate()")
	public void updateAfterReturning(JoinPoint joinPoint) {
		cleanRedisCache(joinPoint);
	}
	/**
	 * 后置操作
	 */
	@AfterReturning("daoDeleteBy()")
	public void deleteAfterReturning(JoinPoint joinPoint) {
		cleanRedisCache(joinPoint);
	}

	/**
	 * 清空缓存
	 * @param joinPoint
	 */
	private void cleanRedisCache(JoinPoint joinPoint) {
		//获取被代理的类
		Object target = joinPoint.getTarget();
		//获取切入方法的数据
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		//获取切入方法
		Method method = signature.getMethod();
		String key ="baseService::"+target.getClass().getSimpleName()+":selectList*";
		Set<Object> stringSet = redisCacheTemplate.keys(key);
		redisCacheTemplate.delete(stringSet);
		log.info("【清空缓存成功】：",key);
	}


}
